package licode.unisop.client.service.filter;

import licode.unisop.client.api.SopPlatform;
import licode.unisop.client.api.SopPlatformMng;
import licode.unisop.client.info.SiAuthorityAction;
import licode.unisop.client.inter.HasAuthority;
import licode.unisop.client.utils.SopErrorCode;
import licode.unisop.client.utils.SopException;
import licode.unisop.client.vo.SopVerifyCode;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.lang.reflect.Method;

/**
 * 权限拦截
 *
 * @author licode
 */
@Aspect
@Configuration
public class SopAuthorityAspect {
    @Resource
    private SopPlatformMng platformMng;

    @Pointcut("@annotation(licode.unisop.client.inter.HasAuthority)")
    public void hasAuthorityVerify() {
    }

    /**
     * 登录验证
     *
     * @param joinPoint 连接点
     */
    @Before("hasAuthorityVerify()")
    public void doAdminAuthVerify(JoinPoint joinPoint) {
        SopVerifyCode checkCode;

        // 判断是否进行权限验证
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        // 从切面中获取当前方法
        Method method = signature.getMethod();

        // 从方法处获取其注解注解
        HasAuthority action = method.getAnnotation(HasAuthority.class);

        String pfName = action.platform();
        SopPlatform platform = platformMng.getPlatform(pfName);

        if (null == platform) {
            throw new SopException(SopErrorCode.PLATFORM_NOT_REGISTER,
                    SopErrorCode.PLATFORM_NOT_REGISTER_MSG);
        }

        checkCode = platform.hasAuthority(SiAuthorityAction.builder()
                .roles(action.roles())
                .permits(action.permits())
                .all(action.all())
                .allRole(action.allRole())
                .allPermit(action.allPermit())
                .build());
        if (checkCode.isNoLogin()) {
            throw new SopException(SopErrorCode.USER_NOT_LOGIN,
                    SopErrorCode.USER_NOT_LOGIN_MSG);
        } else if (!checkCode.isOk()) {
            throw new SopException(SopErrorCode.FORBIDDEN_PERM_GRAND,
                    SopErrorCode.FORBIDDEN_PERM_GRAND_MSG);
        }
    }
}
